// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// d [author] rhyme_lph
// P [email]  rhymelph@gmail.com
// V [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/entities/business_contact_entity.dart';
import 'package:finance_app/src/http_service/http_dashboard_service.dart';
import 'package:finance_app/src/http_service/http_contact_service.dart';
import 'package:finance_app/src/mixin/contacts_sort_mixin.dart';
import 'package:finance_app/src/mixin/filter_contact_sort_mixin.dart';
import 'package:finance_app/src/mixin/format_group_map_mixin.dart';
import 'package:finance_app/src/mixin/search_data_list_mixin.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/utils/date_time_utils.dart';
import 'package:finance_app/src/utils/list_to_map_utils.dart';
import 'package:finance_app/src/utils/reg_exp_utils.dart';
import 'dart:math' as math;

class AllContactsProvider extends BaseProvider
    with
        SearchDataListMixin,
        FilterContactSortMixin,
        ContactsSortMixin,
        FormatGroupMapLocalMixin<BusinessContactEntity> {
  List<BusinessContactEntity> dataList;

  @override
  void initState() {
    super.initState();
    _loadData();
  }

  void _loadData() async {
    await post(HttpDashboardService.dashboardContacts(1), onSuccess: (result) {
      dataList = getEntityFromResult<List<BusinessContactEntity>>(result);
      contactToMap(dataList);
      update();
    });
  }

  void contactToMap(List<BusinessContactEntity> contacts) {
    groupMap.clear();
    if (currentSelectSortContact == S.current.alphabetical) {
      sortGroupToMap(contacts,
          sort: (a, b) => sortNameFirst(a, b, (t) => t.name),
          group: (a) => groupFirstName(a, (t) => t.name),
          filter: _onFilter,
          itemBefore: (map, b) => favoriteBefore(map, b, (b) => b.isFavorite));
      if (groupMap['Favourites'] != null &&
          groupMap['Favourites'].length == 0) {
        groupMap.remove('Favourites');
      }
    } else if (currentSelectSortContact == S.current.recently_transacted) {
      sortGroupToMap(contacts,
          sort: (a, b) =>
              sortIssuesAt(a, b, (t) => t.lastTransactionAt, (t) => t.id),
          filter: _onFilter,
          group: (a) => groupMonth(a, (t) => t.lastTransactionAt));
    } else {
      sortGroupToMap(contacts,
          sort: (a, b) => sortPayAmount(a, b, (t) => t.isFavorite,
              (t) => (t.receivingAmount ?? 0.0) - (t.payingAmount ?? 0.0)),
          filter: _onFilter,
          group: groupOnly);
    }
  }

  @override
  Future get dataFuture => null;

  void onNavViewAll() {
    Routes.navigateTo(RouterGenProviders.allContactsPage);
  }

  void onNavContactDetail(BusinessContactEntity e) {
    Routes.navigateTo(RouterGenProviders.businessContactDetailPage, params: {
      'data': e,
    });
  }

  String searchText;

  @override
  void searchRefreshData(data) {
    contactToMap(dataList);
    update();
  }

  @override
  void sortUpdate() {
    contactToMap(dataList);
  }

  @override
  void onRequestRefresh() {
    contactToMap(dataList);
  }

  bool _onFilter(BusinessContactEntity a) {
    // if(currentSelectFilterList.length == 0) return true;
    bool isNotFilter = false;
    //先判断
    if (RegExpUtils.getSearchRegExp(searchController.text).hasMatch(a.name)) {
      List<bool> hasTrueList = [];
      if (currentSelectFilterList.length == 0) {
        hasTrueList.add(true);
      } else {
        if (currentSelectFilterList.contains('Net Incoming')) {
          //净收入
          hasTrueList.add(a.receivingAmount - a.payingAmount > 0);
        }
        if (currentSelectFilterList.contains('Net Outgoing')) {
          //净支出
          hasTrueList.add(a.receivingAmount - a.payingAmount < 0);
        }
        if (currentSelectFilterList.contains('Overdue Transactions')) {
          hasTrueList.add(a.isOverdue == 1);
        }
        if (currentSelectFilterList.contains('Client')) {
          hasTrueList.add(a.isClient == 1);
        }
        if (currentSelectFilterList.contains('Supplier')) {
          hasTrueList.add(a.isSupplier == 1);
        }
      }
      isNotFilter = hasTrueList.contains(true);
    }
    return isNotFilter;
  }

  void onClickStar(BusinessContactEntity e) async {
    bool isSuccess = false;
    await post(
        HttpContactService.updateContact(e.id,
            is_favorite: e.isFavorite == 1 ? 0 : 1),
        autoHandler: AutoHandler.Toast,
        loadingTip: S.current.loading, onSuccess: (result) {
      isSuccess = true;
    });
    if (isSuccess == true) {
      e.isFavorite = e.isFavorite == 1 ? 0 : 1;
      contactToMap(dataList);
      update();
    }
  }

  void updateContact(BusinessContactEntity entity) {
    final updateData = dataList.firstWhere((element) => element.id == entity.id,
        orElse: () => null);
    if (updateData != null) {
      updateData.fromJson(entity.toJson());
      contactToMap(dataList);
      update();
    } else {
      dataList.add(entity);
      contactToMap(dataList);
      update();
    }
  }

  void onDeleteContact(int id) {
    dataList.removeWhere((element) => element.id == id);
    contactToMap(dataList);
    update();
  }
}
